﻿#ifndef DATAMODEL_H
#define DATAMODEL_H

#include <vector>
#include <set>
#include <map>
#include <string>

struct Attribute;

struct Node
{
    Node(const std::string &name, bool required = false,  Node *parent = nullptr);
    Node(const Node &other) = delete;
    Node(Node &&other) = delete;
    void Destory() const;

    const std::string                                    name;
    std::vector<const Attribute*>                        attrs;
    std::map<std::string, const Node*>                   sub_nodes;
    std::map<std::set<std::string>, const Attribute*>    addition_attrs;
    const bool                                           required{false};
    Node* const                                          parent{nullptr};

    const Node *clone(bool required, Node *new_parent) const;
private:
    ~Node(); // make alive on heap only
};

struct Attribute
{
    Attribute(const std::string &name, bool required = false);
    Attribute(const Node &other) = delete;
    Attribute(Node &&other) = delete;
    void Destory() const;

    const std::string       name;
    const bool              required{false};

    Attribute* clone() const;

private:
    ~Attribute() = default; // make alive on heap only
};

namespace pugi {
    class xml_node;
}

const Node* BuildNodeTreeFromXml(const pugi::xml_node &root, Node *parent = nullptr);
void        ValidationXmlFileWithRule(const pugi::xml_node &root, const Node *rule, std::ostream& out_stream);

#endif // DATAMODEL_H
